/*
* Entourage
* Copyright 2011 INF532@Galatasaray University & Vincent Labatut 
* 
* This file is part of Entourage.
* 
* Entourage is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* Entourage is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with Entourage. If not, see <http://www.gnu.org/licenses/>.
* 
*/

package com.appspot.entourage.explorer;

import java.util.List;

import com.appspot.entourage.common.NamedLink;
import com.appspot.entourage.common.Person;
import com.appspot.entourage.databasemanager.DataBaseManager;
import com.appspot.entourage.freebasechecker.FreebaseChecker;
import com.appspot.entourage.webpageparser.WebPageParser;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import static com.google.appengine.api.taskqueue.TaskOptions.Builder.*;

/**
 * This class is used to control the whole operation of the project, it means 
 * that it manages the web page parsing, freebase checking and database steps.
 * @author Berk PELENK <bpelenk@beengames.com>
 * @see NamedLink
 * @see Person
 * @see DatabaseManager
 * @see FreebaseChecker
 * @version 1
 *
 */
public class Explorer {
	
	public static final int NOT_STARTED = 0;
	public static final int STARTED = 1;
	public static final int PAUSED = 2;
	
	/**
	 * This method starts the whole operation.
	 * @param url Web page link to start the parsing operation
	 * @param radius Maximum distance of the connections to starting person 
	 * @return void
	 * @author Berk PELENK <bpelenk@beengames.com>
	 * @throws Exception 
	 */
	public static void start(String url, int radius) throws Exception
	{		
		DataBaseManager.setStatus(STARTED);
		NamedLink link = WebPageParser.getNamedLink(url);
		Person pers = FreebaseChecker.checkNamedLink(link);
		DataBaseManager.init(radius, pers);
		addTask("");
	}
	
	/**
	 * This method pauses the whole operation.
	 * @return void
	 * @author Berk PELENK <bpelenk@beengames.com>
	 * @throws Exception 
	 */
	public static void pause() throws Exception
	{
		int status = DataBaseManager.getStatus();
		if(status == STARTED)
		{
			Queue queue = QueueFactory.getDefaultQueue();
			queue.purge();
			DataBaseManager.setStatus(PAUSED);
		}
	}
	
	/**
	 * This method continues the whole loop. It first checks if there
	 * are any other person to query, if yes, get the links from the 
	 * wikipedia page of this person, check the ones which are real person
	 * links then add them to database. If not, set the Status to 0.
	 * @return void
	 * @author Berk PELENK <bpelenk@beengames.com>
	 * @throws Exception 
	 */
	public static void continueTo() throws Exception
	{
		int status = DataBaseManager.getStatus();
		if(status == PAUSED)
		{
			DataBaseManager.setStatus(STARTED);
			addTask("");
			return;
		}
		
		Person person = DataBaseManager.getNextPerson();
		if(person == null)
			DataBaseManager.setStatus(NOT_STARTED);
		else
		{
			List<NamedLink> namedLinks = WebPageParser.getNamedLinks(person.getUrl());
			List<Person> personsToAdd = FreebaseChecker.checkNamedLinks(namedLinks);
			DataBaseManager.insertLinks(person, personsToAdd);
			addTask("");
		}
	}
	
	/**
	 * This method stops the whole operation and clears tasks
	 * @return void
	 * @author Berk PELENK <bpelenk@beengames.com>
	 * @throws Exception 
	 */
	public static void stop() throws Exception
	{	
		Queue queue = QueueFactory.getDefaultQueue();
		queue.purge();
		DataBaseManager.setStatus(NOT_STARTED);
	}
	
	/**
	 * This method is used to set status to 1 and
	 * add an initial task
	 * @param url Wikipedia page to parse of the initial person
	 * @param radius Maximum distance to the root person
	 * @return void
	 * @author Berk PELENK <bpelenk@beengames.com>
	 * @throws Exception 
	 */
	public static void prepareToStart(String url, int radius) throws Exception
	{
		int status = DataBaseManager.getStatus();
		if(status == NOT_STARTED)
		{
			DataBaseManager.setStatus(STARTED);
			addTask("url="+url+"&radius="+radius);			
		}
	}
	
	/**
	 * This method adds a scheduled task to GAE task queue
	 * @param arguments Arguments can contain radius and url
	 * @return void
	 * @author Berk PELENK <bpelenk@beengames.com>
	 */
	public static void addTask(String arguments)
	{
		Queue queue = QueueFactory.getDefaultQueue();
        queue.add(withUrl("/executeTask?" + arguments));
	}
}
